package com.contract.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.contract.common.enums.RegisterStateEnum;
import com.contract.common.enums.RegisterTypeEnum;
import com.contract.common.enums.UserStateEnum;
import com.contract.common.error.BizException;
import com.contract.common.error.JsonReturnCode;
import com.contract.common.util.AuthUtil;
import com.contract.common.util.CommonUtil;
import com.contract.common.util.FileUtil;
import com.contract.mapper.BizFileMapper;
import com.contract.mapper.SysRegisterMapper;
import com.contract.mapper.SysUserMapper;
import com.contract.pojo.bo.BizFile;
import com.contract.pojo.bo.SysRegister;
import com.contract.pojo.bo.SysUser;
import com.contract.pojo.dto.IdCardResult;
import com.contract.pojo.input.RegisterQueryInput;
import com.contract.pojo.input.RegisterRejectInput;
import com.contract.pojo.input.RegisterSaveInput;
import com.contract.pojo.output.CardBackOutput;
import com.contract.pojo.output.CardFaceOutput;
import com.contract.pojo.output.CheckFaceOutput;
import com.contract.pojo.output.JsonResult;
import com.contract.pojo.output.PageOutput;
import com.contract.pojo.output.RegisterOutput;
import com.contract.service.common.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.util.Map;

/**
 * 用户service
 *
 * @author liw
 * @version 1.0
 * @date 2022/6/13 11:10
 */
@Slf4j
@Service
public class SysRegisterService extends BaseService {

    @Autowired
    private SysRegisterMapper sysRegisterMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private FileService fileService;

    @Autowired
    private BizFileMapper bizFileMapper;

    /**
     * 新增 注册
     *
     * @param file 数据
     * @return 1
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<CheckFaceOutput> checkFace(MultipartFile file) {
        String rootPath = getFileRootPath();
        BizFile bizFile = FileUtil.file2Local(file, rootPath);
        SysUser sysUser = sysUserMapper.selectById(getUserInfo().getUser().getId());
        String path = bizFileMapper.selectById(sysUser.getCardFace()).getPath();
        boolean b = AuthUtil.comparingFace(rootPath + bizFile.getPath(), getFileRootPath() + path);
        if (b) {
            bizFileMapper.insert(bizFile);
        }
        CheckFaceOutput output = new CheckFaceOutput();
        output.setFileId(bizFile.getId());
        output.setSuccess(b);
        return JsonResult.success(output);
    }

    /**
     * 新增 注册
     *
     * @param file 数据
     * @return CardFaceOutput
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<CardFaceOutput> uploadCardFace(MultipartFile file) {
        String rootPath = getFileRootPath();
        BizFile bizFile = FileUtil.file2Local(file, rootPath);
        IdCardResult result = AuthUtil.cardAnalysis(rootPath + bizFile.getPath(), "front");
        if (result == null || CommonUtil.isEmpty(result.getWordsResult())) {
            throw new BizException(JsonReturnCode.FILE_UPLOAD_ERROR);
        }
        Map<String, IdCardResult.Words> wordsResult = result.getWordsResult();
        CardFaceOutput output = new CardFaceOutput();
        output.setUserName(AuthUtil.getValue("姓名", wordsResult));
        output.setNation(AuthUtil.getValue("民族", wordsResult));
        output.setAddress(AuthUtil.getValue("住址", wordsResult));
        output.setSex(AuthUtil.getValue("性别", wordsResult));
        output.setCardNo(AuthUtil.getValue("公民身份号码", wordsResult));
        output.setBirthday(AuthUtil.getValueDate("出生", wordsResult));
        bizFileMapper.insert(bizFile);
        output.setFileId(bizFile.getId());
        return JsonResult.success(output);
    }

    /**
     * 新增 注册
     *
     * @param file 数据
     * @return 1
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<CardBackOutput> uploadCardBack(MultipartFile file) {

        String rootPath = getFileRootPath();
        BizFile bizFile = FileUtil.file2Local(file, rootPath);
        IdCardResult result = AuthUtil.cardAnalysis(rootPath + bizFile.getPath(), "back");
        if (result == null || CommonUtil.isEmpty(result.getWordsResult())) {
            throw new BizException(JsonReturnCode.FILE_UPLOAD_ERROR);
        }
        Map<String, IdCardResult.Words> wordsResult = result.getWordsResult();
        CardBackOutput output = new CardBackOutput();
        output.setCardStart(AuthUtil.getValueDate("签发日期", wordsResult));
        try {
            output.setCardEnd(AuthUtil.getValueDate("失效日期", wordsResult));
        } catch (Exception e) {
            log.info("失效日期: " + wordsResult.get("失效日期"));
            output.setCardEnd(LocalDate.of(2099, 1, 1));
        }
        output.setOrganization(AuthUtil.getValue("签发机关", wordsResult));
        bizFileMapper.insert(bizFile);
        output.setFileId(bizFile.getId());
        return JsonResult.success(output);
    }

    /**
     * 新增 注册
     *
     * @param vo 数据
     * @return 1
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Long> save(RegisterSaveInput vo) {
        SysRegister sysRegister = dtoConverter.registerSaveVo2Bo(vo);
        sysRegister.setId(getUserInfo().getUser().getId());
        sysRegister.setState(RegisterStateEnum.W.getKey());
        sysRegisterMapper.updateById(sysRegister);
        return JsonResult.success(sysRegister.getId());
    }

    /**
     * 查询列表
     *
     * @param vo 查询条件
     * @return data
     */
    public JsonResult<PageOutput<RegisterOutput>> queryList(RegisterQueryInput vo) {
        LambdaQueryWrapper<SysRegister> qw = new LambdaQueryWrapper<>();
        PageOutput.Node<SysRegister, RegisterOutput> node = new PageOutput.Node<SysRegister, RegisterOutput>()
                .setFun(dtoConverter::registerBo2Vo);
        if (!ObjectUtils.isEmpty(vo.getUserName())) {
            qw.like(SysRegister::getUserName, vo.getUserName());
        }
        qw.eq(SysRegister::getType, RegisterTypeEnum.U.getKey());
        qw.eq(SysRegister::getState, RegisterStateEnum.W.getKey());
        if (Boolean.TRUE.equals(vo.getEnable())) {
            Page<SysRegister> objectPage = new Page<>(vo.getPageNo(), vo.getPageSize());
            objectPage.setOptimizeCountSql(false);
            qw.orderByDesc(SysRegister::getUpdateTime);
            node.setPage(sysRegisterMapper.selectPage(objectPage, qw));
        } else {
            node.setList(sysRegisterMapper.selectList(qw));
        }
        return JsonResult.success(PageOutput.page(node));
    }

    /**
     * 审核通过
     *
     * @param id 操作数据id
     * @return data
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Long> approved(Long id) {
        SysRegister sysRegister = sysRegisterMapper.selectById(id);
        if (CommonUtil.isEmpty(sysRegister)) {
            throw new BizException(JsonReturnCode.NO_REGISTER);
        }
        if (!sysRegister.getState().equals(RegisterStateEnum.W.getKey())) {
            throw new BizException(JsonReturnCode.NO_AUDIT);
        }
        SysUser sysUser = dtoConverter.registerBo2UserBo(sysRegister);
        sysUser.setUpdateTime(null);
        sysUser.setCreateTime(null);
        sysUser.setState(null);
        LambdaQueryWrapper<SysUser> userQw = new LambdaQueryWrapper<>();
        userQw.eq(SysUser::getId, sysRegister.getId());
        Integer count = sysUserMapper.selectCount(userQw);
        if (count != null && count > 0) {
            sysUserMapper.updateById(sysUser);
        } else {
            sysUser.setState(UserStateEnum.N.getKey());
            sysUserMapper.insert(sysUser);
        }
        LambdaUpdateWrapper<SysRegister> qw = new LambdaUpdateWrapper<>();
        qw.eq(SysRegister::getId, sysRegister.getId());
        qw.set(SysRegister::getState, RegisterStateEnum.A.getKey());
        sysRegisterMapper.update(null, qw);
        return JsonResult.success(sysRegister.getId());
    }

    /**
     * 驳回
     *
     * @param vo 操作数据
     * @return data
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Long> reject(RegisterRejectInput vo) {
        LambdaUpdateWrapper<SysRegister> qw = new LambdaUpdateWrapper<>();
        qw.eq(SysRegister::getId, vo.getId());
        qw.set(SysRegister::getState, RegisterStateEnum.R.getKey());
        qw.set(SysRegister::getRejectReason, vo.getRejectReason());
        sysRegisterMapper.update(null, qw);
        return JsonResult.success(vo.getId());
    }

    /**
     * 查询
     *
     * @return data
     */
    public JsonResult<RegisterOutput> queryInfo(Long id) {
        SysRegister user = sysRegisterMapper.selectById(id);
        RegisterOutput userOutput = dtoConverter.registerBo2Vo(user);
        return JsonResult.success(userOutput);
    }

    /**
     * 查询
     *
     * @return data
     */
    public JsonResult<RegisterOutput> queryInfoNon() {
        return queryInfo(getUserInfo().getUser().getId());
    }

}
